
using AutoMapper;
using DTO;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Model;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using RestSharp;
using SqlSugar;
using System.Net;
using Util;

namespace API.Controllers
{
    public class PassRuleController : BaseController
    {
        Repository<tPassRule> _PassRule;
        Repository<tStaff> _Staff;
        Repository<tFace> _Face;
        Repository<tRuleStaff> _tRuleStaff;
        Repository<tDoorRecord> _tDoor;
        readonly IMapper _mapper;
        public PassRuleController(Repository<tPassRule> PassRule, IMapper mapper, Repository<tStaff> staff, Repository<tFace> face, Repository<tRuleStaff> tRuleStaff, Repository<tDoorRecord> tDoor)
        {
            _PassRule = PassRule;
            _mapper = mapper;
            _Staff = staff;
            _Face = face;
            _tRuleStaff = tRuleStaff;
            _tDoor = tDoor;
        }
        /// <summary>
        /// 保存
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<ResultMsg<string>> Save([FromBody] SavePassRuleInput dto)
        {
            ResultMsg<string> result = new ResultMsg<string>();
            try
            {

                tPassRule model = new tPassRule();
                model.FRuleName = dto.RuleName;
                model.FDeleted = false;
                model.FVersion = dto.Version;
                model.FImpassable = JsonConvert.SerializeObject(dto.Impassable);
                model.FPassable = JsonConvert.SerializeObject(dto.Passables);
                model.FWeekday = JsonConvert.SerializeObject(dto.Weekday);
                model.FEnter = dto.Enter;
                model.FDefault = dto.Default;
                model.Id= dto.Id;
                InitEntity(model);
                await _PassRule.InsertOrUpdateAsync(model);

                //默认的规则只能有一个
                var list = await _PassRule.GetListAsync(c => !c.FDeleted && c.Id != model.Id);
                for (int i = 0; i < list.Count; i++)
                {
                    list[i].FDefault = false;
                }
                await _PassRule.UpdateRangeAsync(list);
                return result.Success();
            }
            catch (Exception ex)
            {
                Util.NLOG.LogHelper.Error("PassRuleController--Save:" + ex.ToString());
                return result.Error(ex.ToString());
            }
        }

        /// <summary>
        /// 获取列表
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<ResultMsg<List<PassRuleOutput>>> GetList([FromBody] PassRuleListInput dto)
        {
            ResultMsg<List<PassRuleOutput>> result = new ResultMsg<List<PassRuleOutput>>();
            try
            {
                var exp = Expressionable.Create<tPassRule>();
                exp.And(c => !c.FDeleted);
                if (!string.IsNullOrEmpty(dto.Name))
                {
                    exp.And(x => x.FRuleName.Contains(dto.Name));
                }
                if (dto.Enter != 0)
                {
                    bool enter = dto.Enter == 1 ? true : false;
                    exp.And(x => x.FEnter == enter);
                }
                var list = (await _PassRule.GetListAsync(exp.ToExpression())).OrderByDescending(a => a.CreateTime).Select(t => new PassRuleOutput
                {
                    Id = t.Id,
                    Del = t.FDeleted,
                    Enter = t.FEnter,
                    Impassable = JsonConvert.DeserializeObject<List<ImpassableInfo>>(t.FImpassable),
                    Passable = JsonConvert.DeserializeObject<List<StartAndEnd>>(t.FPassable),
                    RuleName = t.FRuleName,
                    Weekday = JsonConvert.DeserializeObject<List<Weekday>>(t.FWeekday).ToList(),
                    Version = t.FVersion,
                    Default = t.FDefault
                }).ToList();


                return result.Success(list.Skip((dto.PageNum - 1) * dto.PageSize).Take(dto.PageSize).ToList(), list.Count);
            }
            catch (Exception ex)
            {
                Util.NLOG.LogHelper.Error("PassRuleController--GetList:" + ex.ToString());
                return result.Error(ex.ToString());
            }
        }
        /// <summary>
        /// 获取唯一
        /// </summary>
        /// <param name="id">主键ID</param>
        /// <returns></returns>
        [HttpGet]
        public async Task<ResultMsg<PassRuleOutput>> GetTheOne(string id)
        {
            ResultMsg<PassRuleOutput> result = new ResultMsg<PassRuleOutput>();
            try
            {
                var model = await _PassRule.GetByIdAsync(id);
                var dao = _mapper.Map<PassRuleOutput>(model);
                return result.Success(dao);
            }
            catch (Exception ex)
            {
                Util.NLOG.LogHelper.Error("PassRuleController--GetTheOne:" + ex.ToString());
                return result.Error(ex.ToString());
            }
        }
        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="id">主键ID</param>
        /// <returns></returns>
        [HttpGet]
        public async Task<ResultMsg<string>> Del(string id)
        {
            ResultMsg<string> result = new ResultMsg<string>();
            try
            {
                await _PassRule.DeleteByIdAsync(id);
                await _tRuleStaff.DeleteAsync(t => t.FRuleId == id);
                return result.Success();
            }
            catch (Exception ex)
            {
                Util.NLOG.LogHelper.Error("PassRuleController--Del:" + ex.ToString());
                return result.Error(ex.ToString());
            }
        }

        /// <summary>
        /// 获取所有人员
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpGet]
        public async Task<ResultMsg<List<GetStaffOutput>>> GetAllStaff()
        {
            ResultMsg<List<GetStaffOutput>> result = new ResultMsg<List<GetStaffOutput>>();
            try
            {
                var client = new RestClient("https://app.yingdl.com:9527/QA_Login/GetCRMUserAll");
                var request = new RestRequest("", RestSharp.Method.Get);


                var response = client.Execute(request);

                object ret = null;
                if (response.StatusCode == HttpStatusCode.OK)
                {
                    if (response != null && response.Content != null)
                    {
                        ret =JObject.Parse(response.Content);
                        //ret = JsonConvert.DeserializeObject(response.Content);
                    }
                }
                if (ret is JObject jObject)
                {
                    int code = (int)jObject["code"];
                    if (code == 200)
                    {
                        JArray array= (JArray)jObject["data"];
                        tStaff model = new tStaff();
                        tFace faceModel= new tFace();
                        foreach (var jItem in array)
                        {
                            // 通过键名获取值
                            string userId = (string)jItem["UserID"];
                            string UserName = (string)jItem["UserName"];
                            if (_Face.GetList(c => c.FUserId == userId.ToString() && !c.FDeleted).Count() == 0)
                            {
                                faceModel = new tFace();
                                faceModel.FUserId = userId;
                                faceModel.FName = UserName;
                                faceModel.FDeleted = false;
                                faceModel.FPhoto = "";
                                faceModel.CreatorId = CurrentUserId;
                                faceModel.FEnter = false;
                                faceModel.FDoorEnter = false;
                                faceModel.FDoorErrMsg = "";
                                faceModel.FErrMsg = "";
                                faceModel.FValidCycle = "[]";
                                InitEntity(faceModel);
                                await _Face.InsertAsync(faceModel);
                            }
                            if ( await _Staff.CountAsync(c => c.FUserId == userId && !c.FDeleted) == 0)
                            {
                                model = new tStaff();
                                model.FUserId = userId;
                                model.FUserName = UserName;
                                model.FDeleted = false;
                                InitEntity(model);
                                await _Staff.InsertAsync(model);
                            }
                        }
                    }
                    else
                    {
                        
                    }
                }
                var list = (await _Staff.GetListAsync(c => !c.FDeleted)).Select(c => new GetStaffOutput
                {
                    Id = c.FUserId,
                    Name = c.FUserName
                }).ToList();
                return result.Success(list);
            }
            catch (Exception ex)
            {
                Util.NLOG.LogHelper.Error("PassRuleController--GetAllStaff:" + ex.ToString());
                return result.Exception();
            }
        }
        /// <summary>
        /// 获取规则所属人员
        /// </summary>
        /// <param name="Id"></param>
        /// <returns></returns>
        [HttpGet]
        public async Task<ResultMsg<List<GetStaffOutput>>> GetStaffByRuleId(string Id)
        {
            ResultMsg<List<GetStaffOutput>> result = new ResultMsg<List<GetStaffOutput>>();
            try
            {
                var staffList= (await _Staff.GetListAsync(c => !c.FDeleted)).Select(c => new { Id = c.FUserId, Name = c.FUserName }).ToList();
                var list = (await _tRuleStaff.GetListAsync(c => c.FRuleId == Id)).Select(c => new GetStaffOutput
                {
                    Id = c.FUserId.ToString(),
                    Name = staffList.Where(x => x.Id == c.FUserId).FirstOrDefault().Name
                }).ToList();
                return result.Success(list);
            }
            catch (Exception ex)
            {
                Util.NLOG.LogHelper.Error("GetStaffByRuleId--GetAllStaff:" + ex.ToString());
                return result.Exception();
            }
        }

        /// <summary>
        /// 规则添加人员
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<ResultMsg<string>> SaveRuleStaff([FromBody] SaveGroupStaffInput input)
        {
            ResultMsg<string> result = new ResultMsg<string>();
            try
            {
                if (input.Id == null)
                {
                    return result.Error("请选择要添加人员的规则");
                }
                if (input.StaffIds == null)
                {
                    return result.Error("请选择该规则人员");
                }
                await _tRuleStaff.DeleteAsync(c => c.FRuleId == input.Id);
                tRuleStaff model = new tRuleStaff();
                List<tRuleStaff> list = new List<tRuleStaff>();
                foreach (var item in input.StaffIds)
                {
                    model.FRuleId = input.Id;
                    model.FUserId = item;
                    InitEntity(model);
                    list.Add(model);
                }
                _tRuleStaff.InsertRange(list);
                return result.Success();
            }
            catch (Exception ex)
            {
                Util.NLOG.LogHelper.Error("GetStaffByRuleId--SaveRuleStaff:" + ex.ToString());
                return result.Exception();
            }
        }

        /// <summary>
        /// 获取刷脸记录
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<ResultMsg<List<GetDoorRecordOutput>>> GetDoorRecordList([FromBody] GetDoorRecordInput input)
        {
            ResultMsg<List<GetDoorRecordOutput>> result = new ResultMsg<List<GetDoorRecordOutput>>();
            try
            {
                List<GetDoorRecordOutput> list = new List<GetDoorRecordOutput>();
                var exp = Expressionable.Create<tDoorRecord>();
                if (!string.IsNullOrEmpty(input.name))
                {
                    exp.And(x => x.FUserName.Contains(input.name));
                }
                if (input.start_time != null)
                {
                    exp.And(x => x.FRecordTime >= input.start_time);
                }
                if (input.end_time != null)
                {
                    exp.And(x => x.FRecordTime <= input.end_time);
                }
                list = _tDoor.GetList(exp.ToExpression()).OrderByDescending(a => a.CreateTime).ToList().Select(t => new GetDoorRecordOutput
                {
                    userId = t.FUserId,
                    name = t.FUserName,
                    recordTime = t.FRecordTime.ToString("yyyy-MM-dd HH:mm:ss"),
                    recogType = GetRecogType(t.FRecogType),
                    passStatusStr = t.FPassStatus == 0 ? "开门了" : "未开门",
                }).ToList();


                return result.Success(list.Skip((input.PageNum - 1) * input.PageSize).Take(input.PageSize).ToList(), list.Count);
            }
            catch (Exception ex)
            {
                Util.NLOG.LogHelper.Error("GetStaffByRuleId--GetDoorRecordList:" + ex.ToString());
                return result.Exception();
            }
        }
        private string GetRecogType(string type)
        {
            string str = string.Empty;
            //-face - 为人脸识别password - 密码开门manual - 远程开门card - 刷卡开门，人脸或卡模式fingerprint - 指纹验证blacklist - 黑名单记录high_temperature - 高温
            switch (type)
            {
                case "face":
                    str = "人脸识别";
                    break;
                case "password":
                    str = "密码开门";
                    break;
                case "manual":
                    str = "远程开门";
                    break;
                case "card":
                    str = "刷卡开门";
                    break;
                case "fingerprint":
                    str = "指纹验证";
                    break;
                case "blacklist":
                    str = "黑名单";
                    break;
                case "high_temperature":
                    str = "高温";
                    break;
                default:
                    break;
            }
            return str;
        }
    }
}
